package info.thereisonlywe.onenesspathfinder.launcher;

import info.thereisonlywe.core.constants.language.GlobalLanguageConstants;
import info.thereisonlywe.core.font.FontLibrary;
import info.thereisonlywe.core.project.ProjectConstants;
import info.thereisonlywe.core.project.ProjectLocalization;
import info.thereisonlywe.core.project.ProjectSettings;
import info.thereisonlywe.core.toolkit.FileToolkit;
import info.thereisonlywe.core.toolkit.ThreadToolkit;
import info.thereisonlywe.onenesspathfinder.controllers.MasterController;
import info.thereisonlywe.onenesspathfinder.controllers.RecitationController;
import info.thereisonlywe.onenesspathfinder.ui.MainFrame;
import info.thereisonlywe.onenesspathfinder.ui.UIDelegate;
import info.thereisonlywe.onenesspathfinder.user.RuntimeSettings;
import info.thereisonlywe.onenesspathfinder.user.StartupSettings;
import info.thereisonlywe.quran.Quran;
import info.thereisonlywe.quran.QuranicVerse;
import info.thereisonlywe.quran.text.QuranicText;
import info.thereisonlywe.quran.text.QuranicTextList;
import info.thereisonlywe.quran.text.QuranicTextManager;
import info.thereisonlywe.salat.recitation.reciter.ReciterList;

import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Locale;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

public class Main {

	public static RuntimeSettings runtimeSettings = null;
	public static boolean ready = false;

	public static void main(String[] args) throws InvocationTargetException,
			InterruptedException
	{

		preConfigure();

		applyStartupSettings();

		updateTexts();

		loadTexts();

		FileToolkit.clearTrash(new File(QuranicTextManager.TEXTS_PATH));

		loadFonts();

		SwingUtilities.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				try
				{
					UIManager.setLookAndFeel(new NimbusLookAndFeel()
					{
						private static final long serialVersionUID = 1L;

						@Override
						public UIDefaults getDefaults()
						{
							UIDefaults ret = super.getDefaults();
							ret.put("OptionPane.yesButtonText",
									ProjectLocalization.getString(
											ProjectConstants.CORE_PROJECT,
											"Yes"));
							ret.put("OptionPane.noButtonText",
									ProjectLocalization
											.getString(
													ProjectConstants.CORE_PROJECT,
													"No"));
							ret.put("OptionPane.cancelButtonText",
									ProjectLocalization.getString(
											ProjectConstants.CORE_PROJECT,
											"Cancel"));
							ret.put("OptionPane.okButtonText",
									ProjectLocalization
											.getString(
													ProjectConstants.CORE_PROJECT,
													"OK"));
							ret.put("defaultFont", FontLibrary.get(
									FontLibrary.DROID_SANS, Font.BOLD, 13));
							ret.put("List[Selected].textBackground", new Color(
									100, 100, 132));
							ret.put("nimbusSelection", new Color(150, 150, 150));
							ret.put("ToolTip.font", FontLibrary.get(
									FontLibrary.DROID_SANS, Font.BOLD, 12));
							ToolTipManager.sharedInstance()
									.setInitialDelay(250);
							ToolTipManager.sharedInstance().setDismissDelay(
									15000);
							ret.put("nimbusOrange", new Color(0, 174, 27));
							return ret;
						}
					});
					MainFrame.init();
					syncBrowser();
				}
				catch (Exception e)
				{
					e.printStackTrace();
					MasterController.exit(1);
				}
			}
		});

		autoSave();
	}

	private static void loadTexts()
	{
		if (RuntimeSettings.RUNTIME_SETTINGS_FILE.exists())
		{
			runtimeSettings = new RuntimeSettings(true);
		}
		else
		{
			runtimeSettings = new RuntimeSettings(false);
			runtimeSettings.set("mushaf", 0);
			runtimeSettings.set("font.size", 1);
			runtimeSettings.set("recitation.loop", false);
			runtimeSettings.set("recitation.reciter",
					ReciterList.AFASY_RECITER.getName());
			// runtimeSettings.set("recitation.textreciter", null);
			runtimeSettings.set("scratchpad.text", "");
			runtimeSettings.set("section", 1);
			runtimeSettings.set("verse", 1);
			runtimeSettings.set("volume", 50);
		}

		Quran.setMushaf(runtimeSettings.getStringAsInt("mushaf"));

		Runnable readTexts = new Runnable()
		{
			@Override
			public void run()
			{
				if (!QuranicTextManager.updateTextsFile())
				{
					if (!QuranicTextManager.updateTextsFile())
					{
						MasterController.exit(2);
					}
				}
				ArrayList<QuranicText> qt = runtimeSettings.getTexts();
				QuranicTextList.readInTexts(qt);
				ready = true;
			}

		};
		new Thread(readTexts).start();
	}

	private static void applyStartupSettings()
	{
		StartupSettings startupSettings;
		if (StartupSettings.STARTUP_SETTINGS_FILE.exists())
		{
			startupSettings = new StartupSettings(true);
		}
		else
		{
			startupSettings = new StartupSettings(false);
			startupSettings.set("language", "English");
		}

		ProjectSettings.setLocalizationCache(true);
		ProjectSettings.setLocale(new Locale(GlobalLanguageConstants
				.getLanguageCode(startupSettings.getString("language"))));
		ProjectSettings.setPackagesForLocalization(new String[] {
				ProjectConstants.ONENESS_PATHFINDER_PROJECT,
				ProjectConstants.QURAN_PROJECT, ProjectConstants.SALAT_PROJECT,
				ProjectConstants.CORE_PROJECT });
		ProjectLocalization.cacheAll();
	}

	private static void preConfigure()
	{
		ProjectSettings.setVersion("5");
		System.setProperty("awt.useSystemAAFontSettings", "lcd");
		// System.setProperty("swing.aatext", "true");

		try
		{
			System.setProperty("apple.laf.useScreenMenuBar", "true");
			System.setProperty(
					"com.apple.mrj.application.apple.menu.about.name",
					"Oneness Pathfinder " + ProjectSettings.getVersion());
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch (ClassNotFoundException e)
		{
			System.out.println("ClassNotFoundException: " + e.getMessage());
		}
		catch (InstantiationException e)
		{
			System.out.println("InstantiationException: " + e.getMessage());
		}
		catch (IllegalAccessException e)
		{
			System.out.println("IllegalAccessException: " + e.getMessage());
		}
		catch (UnsupportedLookAndFeelException e)
		{
			System.out.println("UnsupportedLookAndFeelException: "
					+ e.getMessage());
		}
	}

	private static void loadFonts()
	{
		FontLibrary.createAndRegister(FontLibrary.SCHERAZADE);
		FontLibrary.createAndRegister(FontLibrary.DROID_SANS);
		FontLibrary.createAndRegister(FontLibrary.CODE2000);
	}

	private static void updateTexts()
	{
		QuranicTextManager.updateTextLengthsFile();
		ArrayList<Integer> ids = QuranicTextManager.getOutdatedTextIDs();
		if (ids.size() > 0)
		{
			int r = JOptionPane.showConfirmDialog(null, ProjectLocalization
					.getString(ProjectConstants.CORE_PROJECT,
							"UpdateConfirmation"), "Oneness Pathfinder "
					+ ProjectSettings.getVersion(), JOptionPane.YES_NO_OPTION);
			if (r == JOptionPane.OK_OPTION)
			{
				for (int i = 0; i < ids.size(); i++)
				{
					QuranicTextManager.updateText(ids.get(i));
				}
			}
		}
	}

	private static final void autoSave()
	{
		Runnable autoSave = new Runnable()
		{
			@Override
			public void run()
			{
				while (true)
				{
					ThreadToolkit.sleep(15000); // every 15secs
					UIDelegate.saveSettings();
					UIDelegate.BookmarkPaneHook.getBookmarkList()
							.saveBookmarks(
									new File("userdata" + File.separator
											+ "bookmarks.qbm"));
				}
			}

		};
		new Thread(autoSave).start();
	}

	private static void syncBrowser()
	{
		Runnable r = new Runnable()
		{
			@Override
			public void run()
			{
				ThreadToolkit.sleep(10000);
				while (true)
				{
					if (RecitationController.getImam().isAlive())
					{
						UIDelegate.engageBrowserLock();
						UIDelegate.NavigationBarHook.switchRecitationState(1);
						QuranicVerse v = RecitationController.getImam()
								.getVerse();
						if (RecitationController.getImam().getDhikr()
								.getNumberOfVersesRemaining() <= 0
								&& !RecitationController.getImam().getLoop())
						{
							UIDelegate.disEngageBrowserLock();
						}

						else
						{
							while (v == null && UIDelegate.isBrowserLocked())
							{
								ThreadToolkit.sleep(10);
								v = RecitationController.getImam().getVerse();
							}
							if (UIDelegate.getDisplayedVerse() != v
									&& !RecitationController.getImam()
											.isPaused())
							{
								if (UIDelegate.isDialogOpen())
								{
									RecitationController.getImam().terminate();
									UIDelegate.NavigationBarHook
											.switchRecitationState(2);
									while (UIDelegate.isDialogOpen())
									{
										ThreadToolkit.sleep(10);
									}
									RecitationController.getImam().revive();
									ThreadToolkit.sleep(250);
									UIDelegate.NavigationBarHook
											.switchRecitationState(1);
								}
								UIDelegate.seekToVerse(v);
							}
							else if (RecitationController.getImam().isPaused())
							{
								UIDelegate.NavigationBarHook
										.switchRecitationState(2);
								while (RecitationController.getImam()
										.isPaused())
								{
									ThreadToolkit.sleep(10);
								}
								ThreadToolkit.sleep(250);
								if (RecitationController.getImam().isAlive())
									UIDelegate.NavigationBarHook
											.switchRecitationState(1);
							}
						}
					}
					else
					{
						UIDelegate.disEngageBrowserLock();
						UIDelegate.NavigationBarHook.switchRecitationState(0);
					}
					ThreadToolkit.sleep(100);
				}
			}
		};
		new Thread(r).start();
	}
}
